/**
 * @Date 2025/1/8 10:25
 * @Created by 衡盛永
 */

package org.example.deploy.common;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import org.apache.shiro.authc.AuthenticationException;
//import org.apache.shiro.authc.AuthenticationInfo;
//import org.apache.shiro.authc.AuthenticationToken;
//import org.apache.shiro.authc.UsernamePasswordToken;
//import org.apache.shiro.authc.SimpleAuthenticationInfo;
//import org.apache.shiro.authc.UnknownAccountException;
//import org.apache.shiro.authz.AuthorizationInfo;
//import org.apache.shiro.authz.SimpleAuthorizationInfo;
//import org.apache.shiro.realm.AuthorizingRealm;
//import org.apache.shiro.subject.PrincipalCollection;
import org.example.deploy.pojo.SysPermission;
import org.example.deploy.pojo.SysRole;
import org.example.deploy.pojo.SysUser;
import org.example.deploy.service.SysPermissionService;
import org.example.deploy.service.SysRoleService;
import org.example.deploy.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;
import java.util.HashSet;

@Component
public class ShiroRealm
//        extends AuthorizingRealm
{
    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysPermissionService sysPermissionService;

    /**
     * 授权
     * Shiro 的授权逻辑执行通常发生在以下几个时机：
     * 1. 用户访问受保护资源时：由过滤器链控制。
     * 2. 显式调用角色或权限检查方法时：如 hasRole 或 checkPermission。
     * 3. 使用注解声明访问控制时：如 @RequiresRoles 和 @RequiresPermissions。
     * 4. 前端根据角色或权限动态加载界面时：通过后端返回的角色和权限数据。
     * 5. 会话恢复时：从缓存加载或调用 Realm 获取用户授权信息。
     */
//    @Override
//    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        System.out.println("授权");
//        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//
//        // 获取当前用户的用户名
//        String username = (String) principalCollection.getPrimaryPrincipal();
//        // 假设在数据库中查询到该用户的角色信息
//        SysUser curUser = sysUserService.getUserByUserName(username);
//        Integer roleId = sysUserService.getRoleIdByUserId(curUser.getId());
//        // 获取权限
//        List<SysPermission> permissionsByRoleId = sysPermissionService.getPermissionsByRoleId(roleId);
//        // 获取角色
//        SysRole role = sysRoleService.getOne(new QueryWrapper<SysRole>().eq("id", roleId));
//        // 根据角色id获取拥有的权限
//        Set<String> roles = new HashSet<>();
//        roles.add(role.getRoleRemark());
//        HashSet<String> permissions = new HashSet<>();
//        // 将角色信息设置到AuthorizationInfo中
//        authorizationInfo.setRoles(roles);
//        for (SysPermission permission : permissionsByRoleId) {
//            permissions.add(permission.getPermissionRemark());
//        }
//        // 将用户权限设置到AuthorizationInfo中
//        authorizationInfo.setStringPermissions(permissions);
//        return authorizationInfo;
//    }
//
//    /**
//     * 身份认证
//     * 客户端传来的 username 和 password 会自动封装到 token，
//     * 先根据 username 进行查询，如果返回 null，则表示用户名错误，直接 return null 即可，Shiro 会自动抛出 UnknownAccountException 异常。
//     * 如果返回不为 null，则表示用户名正确，再验证密码，直接返回  SimpleAuthenticationInfo 对象即可，如果密码验证成功，Shiro 认证通过，否则返回 IncorrectCredentialsException 异常。
//     */
//    @Override
//    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//        System.out.println("认证");
//        // 将AuthenticationToken转换为UsernamePasswordToken
//        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//
//        // 从token中获取用户名
//        String username = token.getUsername();
//        // 在实际项目中，这里通常是从数据库中根据用户名查询用户信息
//        SysUser curUser = sysUserService.getUserByUserName(username);
//        if (curUser == null) {
//            throw new UnknownAccountException("用户不存在");
//        }
//
//        // 假设数据库中的密码是经过加密的，这里为了演示使用明文密码
//        String password = curUser.getPassword();
//        System.out.println("username:" + username + "password:" + password);
//
//        // 返回认证信息，包括用户名和密码
//        return new SimpleAuthenticationInfo(username, password, getName());
//    }
}
